const base = require("../base/controllerBase");
const moment = require("moment");
const _ = require("lodash");

class IotDeviceController extends base {
    async createLog() {
        const {ctx, service} = this;
        try {
            const {body} = ctx.request;
            console.log("收到日志消息", body);
            const model = {
                payload: {type: 'object'},
                topic: {type: 'string'}
            };
            ctx.validate(model, body);
            this.app.eventBus.emit("HTTP_DATA_RECEVED", body);
            // const result = await this.app.deviceMgr.onData(body);
            ctx.body = {status: "ok"};
            ctx.status = 200;
        } catch (e) {
            console.error(e);
            console.log(ctx.request.body);
            const _message = e && e.message ? e.message : this.ERROR_MSG;
            ctx.body = {status: 'error', message: _message, result: e};
            ctx.status = 200;
        }
    }

    async createDevice() {
        const {ctx, service} = this;
        try {
            const {body} = ctx.request;
            const model = {
                tenantCode: {type: 'string'}
            };

            ctx.validate(model, body);
            const {tenantCode} = body;
            const {modelCode, deviceName} = body;
            const tm = await ctx.app.dbs.findOne("ThingModel", {tenantCode, code: modelCode});
            console.log('tm', tm);
            if (!tm) {
                throw new Error(deviceName + ' 的物模型编码不存在！');
            }

            const {deviceType, name} = tm;
            body.deviceType = deviceType;
            body.modelName = name;
            const result = await ctx.app.dbs.insert('IotDevice', body);
            ctx.body = {status: "ok", result};
            ctx.status = 200;
        } catch (e) {
            console.error(e);
            console.log(ctx.request.body);
            const _message = e && e.message ? e.message : this.ERROR_MSG;
            ctx.body = {status: 'error', message: _message, result: e};
            ctx.status = 200;
        }
    }

    async createDeviceMany() {
        const {ctx, service} = this;
        try {
            const {body} = ctx.request;

            const model = {
                devices: {type: 'array'}, tenantCode: {type: 'string'}
            };
            const {devices, tenantCode} = body;
            ctx.validate(model, body);
            //   console.log('bbb', body);
            for (const device of devices) {

            }
            _.map(devices, async (device) => {
                device.tenantCode = tenantCode;
                const {modelCode} = device;
                const tm = await ctx.app.dbs.findOne("ThingModel", {tenantCode, code: modelCode});
                console.log('tm', tm);
                if (tm) {
                    const {deviceType, name} = tm;
                    device.deviceType = deviceType;
                    device.modelName = name;
                }
            });
            const result = await ctx.app.dbs.insertMany('IotDevice', devices);
            ctx.body = {status: "ok", result};
            ctx.status = 200;
        } catch (e) {
            console.error(e);
            console.log(ctx.request.body);
            const _message = e && e.message ? e.message : this.ERROR_MSG;
            ctx.body = {status: 'error', message: _message, result: e};
            ctx.status = 200;
        }
    }

    async clearDevice() {
        const {ctx, service} = this;
        try {
            const {body} = ctx.request;
            const model = {
                treeId: {type: 'string'},
                tenantCode: {type: 'string'}
            };

            ctx.validate(model, body);
            //   delete body['tenantCode'];
            const {treeId} = body;
            console.log('clear device', body);
            const result = await ctx.app.dbs.deleteMany('IotDevice', {treeId});
            const result1 = await ctx.app.dbs.deleteMany('IotReportData', {treeId});
            const result2 = await ctx.app.dbs.deleteMany('DeviceCache', {treeId});

            ctx.body = {status: "ok", result};
            ctx.status = 200;
        } catch (e) {
            console.error(e);
            console.log(ctx.request.body);
            const _message = e && e.message ? e.message : this.ERROR_MSG;
            ctx.body = {status: 'error', message: _message, result: e};
            ctx.status = 200;
        }
    }

    async findDevice() {
        const {ctx, service} = this;
        try {
            const {body} = ctx.request;
            const model = {
                tenantCode: {type: 'string'},
                deviceId: {type: 'string'}
            };

            ctx.validate(model, body);

            const {treeId, deviceId, tenantCode} = body;
            const query = {tenantCode, deviceId};
            if (treeId) query['treeId'] = treeId;

            const result = await ctx.app.dbs.findOne('IotDevice', query);

            ctx.body = {status: "ok", result};
            ctx.status = 200;
        } catch (e) {
            console.error(e);
            console.log(ctx.request.body);
            const _message = e && e.message ? e.message : this.ERROR_MSG;
            ctx.body = {status: 'error', message: _message, result: e};
            ctx.status = 200;
        }
    }

    async findDeviceMany() {
        const {ctx, service} = this;
        try {
            const {body} = ctx.request;
            const model = {
                tenantCode: {type: 'string'}
            };

            ctx.validate(model, body);
            //   delete body['tenantCode'];
            const {treeId, deviceId, tenantCode, status, deviceType, deviceName} = body;
            console.log('findDeviceMany bodyy', body);
            const query = status === null || status === undefined ? {tenantCode} : {tenantCode, status};
            if (treeId) query['treeId'] = treeId;

            if (deviceId) {
                query['deviceId'] = {$regex: deviceId};
            }
            if (deviceName) {
                query['deviceName'] = {$regex: deviceName};
            }
            if (deviceType) {
                query['deviceType'] = {$regex: deviceType};
            }
            console.log('queryquery', query);
            const sort = deviceType === '末端空调' ? {"points.envTemp": -1} : undefined;
            const result = await ctx.app.dbs.find('IotDevice', query, sort);
            //  console.log('find device many', result);

            // if (deviceType && deviceType === '末端空调') {
            //     _.map(result, item => {
            //         const {points = {}} = item;
            //         const {envTemp, setTemp} = points;
            //         item.envTemp = envTemp;
            //         item.setTemp = setTemp;
            //     });
            // }
            ctx.body = {status: "ok", result};
            ctx.status = 200;
        } catch (e) {
            console.error(e);
            console.log(ctx.request.body);
            const _message = e && e.message ? e.message : this.ERROR_MSG;
            ctx.body = {status: 'error', message: _message, result: e};
            ctx.status = 200;
        }
    }

    async findDeviceDataMany() {
        const {ctx, service} = this;
        try {
            const {body} = ctx.request;
            console.log('findDeviceDataMany', body);
            const model = {
                tenantCode: {type: 'string'},
                deviceId: {type: 'string'},
                path: {type: 'string'}
            };
            ctx.validate(model, body);
            const {deviceId, tenantCode, path, time} = body;

            const query = {deviceId, tenantCode};

            if (time && time.length === 2) {
                const start = moment(time[0]).valueOf();
                const end = moment(time[1]).valueOf();
                query['time'] = {$gt: start, $lt: end};
            }
            console.log('find device data query', query);
            const res = await ctx.app.dbs.find('IotReportData', query, {time: -1});

            const result = [];
            _.map(res, (v, i) => {
                const {time, points} = v;
                result.push({time: moment(time).format('YYYY-MM-DD HH:mm:ss'), value: points[path]});
            });
            console.log('find device data many', result);
            ctx.body = {status: "ok", result};
            ctx.status = 200;
        } catch (e) {
            console.error(e);
            console.log(ctx.request.body);
            const _message = e && e.message ? e.message : this.ERROR_MSG;
            ctx.body = {status: 'error', message: _message, result: e};
            ctx.status = 200;
        }
    }

    async settingAirInitValueBatch() {
        const {ctx, service} = this;
        try {
            const {body} = ctx.request;
            console.log(body);
            const model = {
                initValue: {type: 'number'}
            };

            ctx.validate(model, body);
            const {initValue} = body;
            const result = await ctx.app.dbs.updateMany('IotDevice', {deviceType: '末端空调'}, {initValue});
            console.log('find device many', result);
            ctx.body = {status: "ok", result};
            ctx.status = 200;
        } catch (e) {
            console.error(e);
            console.log(ctx.request.body);
            const _message = e && e.message ? e.message : this.ERROR_MSG;
            ctx.body = {status: 'error', message: _message, result: e};
            ctx.status = 200;
        }
    }

    async settingAirInitValue() {
        const {ctx, service} = this;
        try {
            const {body} = ctx.request;
            console.log(body);
            const model = {
                initValue: {type: 'number'},
                deviceId: {type: 'string'}
            };

            ctx.validate(model, body);
            const {initValue, deviceId} = body;
            const result = await ctx.app.dbs.updateOne('IotDevice', {deviceType: '末端空调', deviceId}, {initValue});
            console.log('find device many', result);
            ctx.body = {status: "ok", result};
            ctx.status = 200;
        } catch (e) {
            console.error(e);
            console.log(ctx.request.body);
            const _message = e && e.message ? e.message : this.ERROR_MSG;
            ctx.body = {status: 'error', message: _message, result: e};
            ctx.status = 200;
        }
    }

    async findAirInitValue() {
        const {ctx, service} = this;
        try {
            const result = await ctx.app.dbs.find('IotDevice', {deviceType: '末端空调'});
            console.log('find device many', result);
            ctx.body = {status: "ok", result};
            ctx.status = 200;
        } catch (e) {
            console.error(e);
            console.log(ctx.request.body);
            const _message = e && e.message ? e.message : this.ERROR_MSG;
            ctx.body = {status: 'error', message: _message, result: e};
            ctx.status = 200;
        }
    }

    /**
     * 物模型相关
     * @returns {Promise<void>}
     */
    async createThingModel() {
        const {ctx, service} = this;
        try {
            const {body} = ctx.request;
            const model = {
                code: {type: 'string'}
            };
            ctx.validate(model, body);
            const {code} = body;
            console.log('create thing model', body);
            const temp = await ctx.app.dbs.find('ThingModel', {code});
            console.log('create thing model temp', temp);
            if (temp.length) {
                throw new Error('物模型编码已存在：' + code);
            }
            const result = await ctx.app.dbs.insert('ThingModel', body);
            console.log('createThingModel result', result);
            ctx.body = {status: "ok", result};
            ctx.status = 200;
        } catch (e) {
            console.error(e);
            console.log(ctx.request.body);
            const _message = e && e.message ? e.message : this.ERROR_MSG;
            ctx.body = {status: 'error', message: _message, result: e};
            ctx.status = 200;
        }
    }

    async updateThingModel() {
        const {ctx, service} = this;
        try {
            const {body} = ctx.request;
            const model = {
                code: {type: 'string'},
                tenantCode: {type: 'string'}
            };
            ctx.validate(model, body);
            const {code, tenantCode} = body;
            const result = await ctx.app.dbs.updateOne('ThingModel', {code, tenantCode}, body);
            // console.log('find device data many', result);
            ctx.body = {status: "ok", result};
            ctx.status = 200;
        } catch (e) {
            console.error(e);
            console.log(ctx.request.body);
            const _message = e && e.message ? e.message : this.ERROR_MSG;
            ctx.body = {status: 'error', message: _message, result: e};
            ctx.status = 200;
        }
    }

    async deleteThingModel() {
        const {ctx, service} = this;
        try {
            const {body} = ctx.request;
            const model = {
                code: {type: 'string'},
                tenantCode: {type: 'string'}
            };
            ctx.validate(model, body);
            const {code, tenantCode} = body;
            const temp = await ctx.app.dbs.find('IotDevice', {modelCode: code, tenantCode});
            console.log('create thing model temp', temp);
            if (temp.length) {
                throw new Error('物模型已创建设备，请先删除设备');
            }
            const result = await ctx.app.dbs.deleteOne('ThingModel', {code, tenantCode});
            // console.log('find device data many', result);
            ctx.body = {status: "ok", result};
            ctx.status = 200;
        } catch (e) {
            console.error(e);
            console.log(ctx.request.body);
            const _message = e && e.message ? e.message : this.ERROR_MSG;
            ctx.body = {status: 'error', message: _message, result: e};
            ctx.status = 200;
        }
    }

    async findThingModel() {
        const {ctx, service} = this;
        try {
            const {body} = ctx.request;
            const model = {
                tenantCode: {type: 'string'},
                code: {type: 'string'}
            };
            ctx.validate(model, body);
            const {tenantCode, code} = body;
            const result = await ctx.app.dbs.findOne('ThingModel', {tenantCode, code});
            //    console.log('find device data many', result);
            ctx.body = {status: "ok", result};
            ctx.status = 200;
        } catch (e) {
            console.error(e);
            console.log(ctx.request.body);
            const _message = e && e.message ? e.message : this.ERROR_MSG;
            ctx.body = {status: 'error', message: _message, result: e};
            ctx.status = 200;
        }
    }

    async findThingModelMany() {
        const {ctx, service} = this;
        try {
            const {body} = ctx.request;
            const model = {
                tenantCode: {type: 'string'}
            };
            ctx.validate(model, body);
            const {tenantCode} = body;
            const result = await ctx.app.dbs.find('ThingModel', {tenantCode});
            //    console.log('find device data many', result);
            ctx.body = {status: "ok", result};
            ctx.status = 200;
        } catch (e) {
            console.error(e);
            console.log(ctx.request.body);
            const _message = e && e.message ? e.message : this.ERROR_MSG;
            ctx.body = {status: 'error', message: _message, result: e};
            ctx.status = 200;
        }

    }

    async findDeviceTypeMany() {
        const {ctx, service} = this;
        try {
            ctx.body = {
                status: "ok",
                result: ["制冷主机", "冷冻水泵", "冷却水泵", "冷却塔", "末端空调", "智能电表", "传感器", "电动阀门", "热泵", "其它设备"]
            };
            ctx.status = 200;
        } catch (e) {
            console.error(e);
            console.log(ctx.request.body);
            const _message = e && e.message ? e.message : this.ERROR_MSG;
            ctx.body = {status: 'error', message: _message, result: e};
            ctx.status = 200;
        }

    }
}

module.exports = IotDeviceController;
